#include <iostream>
#include <unistd.h>
#include <string>
#include <unistd.h>
#include <sys/time.h>

#include "zmq.h"
#include "send_data_generated.h"

using namespace std;

#define SUMMARY_EVERY_US 1000000
#define FrameSize  3*1024* 1024 // 3*1024* 1024
#define PARAM_SIZE 1024
#define RATE_LIMIT  1


uint64_t now_microseconds(void) {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return (uint64_t)tv.tv_sec * 1000000 + (uint64_t)tv.tv_usec;
}


void microsleep(int usec) {
  struct timespec req;
  req.tv_sec = 0;
  req.tv_nsec = 1000 * usec;
  nanosleep(&req, NULL);
}


//发布订阅模型，发布者
int publisher()
{
  void* context = zmq_ctx_new();
  void* publisher = zmq_socket(context, ZMQ_PUB);

  /* 修改socket 的收发缓冲区大小为 32M bytes */
  // int sendbuff = 32*1024*1024;
  // zmq_setsockopt(publisher, ZMQ_SNDBUF, (void *)&sendbuff, sizeof(int));
  // int recvbuff = 32*1024*1024;
  // zmq_setsockopt(publisher, ZMQ_RCVBUF, (void *)&recvbuff, sizeof(int));

  //int ret = zmq_bind(publisher, "ipc:///tmp/test");
  int ret = zmq_bind(publisher, "tcp://*:5558");

  int i = 0;
  int sent = 0;
  uint64_t start_time = now_microseconds();
  uint64_t next_summary_time = start_time + SUMMARY_EVERY_US;
  int previous_sent = 0;
  uint64_t previous_report_time = start_time;


  while(1)
  {
    flatbuffers::FlatBufferBuilder builder;
    uint64_t now1 = now_microseconds();
    int8_t buf[FrameSize] = {1};
    auto data = builder.CreateVector(buf, FrameSize);
    uint64_t now = now_microseconds();
    auto send_data_fb = SendData::CreateSendDataSt(builder, now / 1000, data);
    builder.Finish(send_data_fb);
    uint64_t now2 = now_microseconds();
    printf("time1:%ld\ntime2:%ld\n", now1, now2);// 计算构造3M数据需要的时间，大概是2~3ms
    printf("send size:%d\n", builder.GetSize());
    ret = zmq_send(publisher, builder.GetBufferPointer(), builder.GetSize(), 0);
    i++;

    sent++;
    if (now > next_summary_time)
    {
      int countOverInterval = sent - previous_sent;
      double intervalRate =countOverInterval / ((now - previous_report_time) / 1000000.0);
      printf("%d ms: Sent %d - %d since last report (%d Hz)\n",
              (int)(now - start_time) / 1000, sent, countOverInterval,(int)intervalRate);

      previous_sent = sent;
      previous_report_time = now;
      next_summary_time += SUMMARY_EVERY_US;
    }

    while (((i * 1000000.0) / (now - start_time)) > RATE_LIMIT)
    {
        microsleep(2000);
        now = now_microseconds();
    }
  }

  zmq_close (publisher);
  zmq_ctx_destroy (context);

  return 0;
}


int main() {
  cout << "hello world" << endl;
  publisher();

  return 0;
}